//
//  ILGCodeSnippet.m
//  ILGDemo
//
//  Created by happy on 2020/2/14.
//  Copyright © 2020 Happy. All rights reserved.
//

#import "ILGCodeSnippet.h"

@implementation ILGCodeSnippet

#pragma mark - 定时器

- (void)registerNSTimer
{
    // 任务耗时太久，0.2变得没有意义啦 14:20 - 15:08  54:74 - 55:60
    __block int count = 5;
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.2 repeats:YES block:^(NSTimer * _Nonnull timer) {
        NSLog(@"NSTimer scheduled");
        
        count--;
        
        dispatch_async(dispatch_get_main_queue(), ^{
            if (count == 4) {
                for (int i = 0; i < 5200; i++) {
                    NSLog(@"for %d", i);
                }
            }
        });
        
        if (count < 0) {
            [timer invalidate];
        }
    }];
    timer.tolerance = 0.0000;
}

- (void)registerDisplayLink
{
    CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(actionForDisplayLink:)];
    displayLink.preferredFramesPerSecond = 5;
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}

static int countD = 5;
- (void)actionForDisplayLink:(CADisplayLink *)displayLink
{
    NSLog(@"actionForDisplayLink");
    
    if (countD == 5) {
        for (int i = 0; i < 5400; i++) {
            NSLog(@"for %d", i);
        }
    }
    
    countD--;

    if (countD <= 0) {
        [displayLink invalidate];
    }
}

- (void)registerDispatchTimer
{
    __block int count = 5;
    
    [self scheduledTimerOfDispatchSourceWithTimerInterval:10 tolarance:0 callback:^(dispatch_source_t timer) {
        NSLog(@"dispatch_source_set_event_handler %@", [NSThread currentThread]);
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"dispatchTimer");
            
//            for (int i = 0; i < 20000; i++) {
//                NSLog(@"for %d", i);
//            }
        });
        
        count--;
        if (count <= 0) {
            dispatch_cancel(timer);
        }
    }];
}

/**
 使用计时器dispatch_source_t

 @param interval 间隔
 @param tolerance 允许误差
 @param callback 回调，在子线程调用的
 @return timer
 */
- (dispatch_source_t)scheduledTimerOfDispatchSourceWithTimerInterval:(NSTimeInterval)interval tolarance:(int)tolerance callback:(void(^)(dispatch_source_t timer))callback
{
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, quene);
    dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, interval * NSEC_PER_SEC, tolerance * NSEC_PER_SEC);
    dispatch_source_set_event_handler(timer, ^{
        callback(timer);
    });
    dispatch_resume(timer);
    
    return timer;
}


#pragma mark - others

- (void)setupObserverForCurrentRunloop
{
    CFRunLoopObserverRef observer = CFRunLoopObserverCreateWithHandler(CFAllocatorGetDefault(), kCFRunLoopAllActivities, YES, 0, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
        switch (activity) {
            case kCFRunLoopEntry:
                NSLog(@"RunLoop进入 %@", [NSRunLoop currentRunLoop].currentMode);
                break;
            case kCFRunLoopBeforeTimers:
                NSLog(@"RunLoop要处理Timers了");
                break;
            case kCFRunLoopBeforeSources:
                NSLog(@"RunLoop要处理Sources了");
                break;
            case kCFRunLoopBeforeWaiting:
                NSLog(@"RunLoop要休息了");
                break;
            case kCFRunLoopAfterWaiting:
                NSLog(@"RunLoop醒来了");
                break;
            case kCFRunLoopExit:
                NSLog(@"RunLoop退出了");
                break;
                
            default:
                break;
        }
    });
    // 给RunLoop添加监听者
    CFRunLoopAddObserver(CFRunLoopGetCurrent(), observer, kCFRunLoopCommonModes);
    
//    // 2.子线程需要开启RunLoop
//    [[NSRunLoop currentRunLoop] run];
    CFRelease(observer);
}

@end
